package com.lyy.lottery.service.activitystatus.impl;

import com.lyy.lottery.common.errorcode.ServiceErrorCodeConstants;
import com.lyy.lottery.common.exception.ServiceException;
import com.lyy.lottery.service.ActivityService;
import com.lyy.lottery.service.activitystatus.ActivityStatusManager;
import com.lyy.lottery.service.activitystatus.operator.AbstractActivityOperator;
import com.lyy.lottery.service.dto.ConvertActivityStatusDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

@Component
@Slf4j
public class ActivityStatusManagerImpl implements ActivityStatusManager {

    //一个自动装配的Map，存储所有AbstractActivityOperator实现类的实例，key为bean名称
    @Autowired
    private final Map<String, AbstractActivityOperator> operatorMap=new HashMap<>();
    @Autowired
    private ActivityService activityService;

    @Override
    @Transactional(rollbackFor = Exception.class)// 发生任何异常都会回滚事务
    public void handlerEvent(ConvertActivityStatusDTO convertActivityStatusDTO) {
        log.info("convertActivityStatusDTO：{}",convertActivityStatusDTO);
        //1、检查operatorMap是否为空
        if (CollectionUtils.isEmpty(operatorMap)){
            log.warn("operatorMap为空！");
            return;
        }
        //2、创建临时Map
//        Map<String, AbstractActivityOperator> currMap=new HashMap<>();
        Map<String,AbstractActivityOperator> currMap = new HashMap<>(operatorMap);
        log.info("currMap:{}",currMap);
        //3、分2个阶段处理状态转换
        Boolean update=false;
        //1）先处理人员、奖品的状态
        update=processConvertStatus(convertActivityStatusDTO,currMap,1);
        //2）后处理活动状态 false||true--x  true||true--v  false||false--x  false|| false|| false--x
        update=processConvertStatus(convertActivityStatusDTO,currMap,2) || update;

        //4、如果有状态更新，则缓存活动信息
        if (update)  activityService.cacheActivity(convertActivityStatusDTO.getActivityId());
    }

    @Override
    public void rollbackHandleEvent(ConvertActivityStatusDTO activityStatusDTO) {
        for (AbstractActivityOperator operator : operatorMap.values()){
            operator.convert(activityStatusDTO);
        }
        //缓存更新
        activityService.cacheActivity(activityStatusDTO.getActivityId());
    }

    private Boolean processConvertStatus(ConvertActivityStatusDTO convertActivityStatusDTO, Map<String, AbstractActivityOperator> currMap, int sequence) {
        Boolean update=false;
        //遍历currMap
        Iterator<Map.Entry<String,AbstractActivityOperator>> iterator=currMap.entrySet().iterator();

        while (iterator.hasNext()){
            AbstractActivityOperator operator=iterator.next().getValue();

            //operator是否需要转换
            if (operator.sequence() != sequence || !operator.needConvert(convertActivityStatusDTO))
                continue;

            //需要转换
            if (!operator.convert(convertActivityStatusDTO)){
                log.info("{}状态转换失败！",operator.getClass().getName());
                throw new ServiceException(ServiceErrorCodeConstants.ACTIVITY_STATUS_CONVERT_ERROR);
            }
            //currMap删除当前operator
            iterator.remove();
            update=true;
        }
        //返回
        return update;
    }

}

























